package com.gengine.media.core.play
{
	import com.gengine.media.events.*;
	import com.gengine.media.interfaces.*;
	import flash.events.*;
	import flash.media.*;
	import flash.net.*;
	import flash.utils.*;
	
	public class NetStreamPlayCore extends MediaPlayCore implements IMediaPlayCore
	{
		private var _nc:NetConnection;
		private var _ns:NetStream;
		private var _timer:Timer;
		private var _startPlay:Boolean = false;
		private var _seekPause:Boolean = false;
		private var _seekTime:Number = 0;
		
		public function NetStreamPlayCore(param1:String = null, param2:Number = 1000, param3:Boolean = false, param4:Number = 250, param5:Object = null)
		{
			super(param1, param2, param5);
			this._timer = new Timer(param4);
			this._timer.addEventListener(TimerEvent.TIMER, this.playingStateTimerEventHandler);
			this._nc = new NetConnection();
			this._nc.connect(null);
			this._nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, this.asyncErrorEventHandler);
			this._nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.securityErrorEventHandler);
			this._ns = new NetStream(this._nc);
			this._ns.bufferTime = param2 / 1000;
			this._ns.checkPolicyFile = param3;
			this._ns.client = {onMetaData:this.onMetaDataHandler, onCuePoint:this.onCuePointHandler};
			this._ns.addEventListener(NetStatusEvent.NET_STATUS, this.netStatusEventHandler);
			this._ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, this.asyncErrorEventHandler);
			this._ns.addEventListener(IOErrorEvent.IO_ERROR, this.ioErrorEventHandler);
			
		}
		
		override public function set volume(param1:Number) : void
		{
			var _loc_2:SoundTransform = null;
			super.volume = param1;
			if (this._ns)
			{
				_loc_2 = this._ns.soundTransform;
				_loc_2.volume = _mute ? (0) : (param1);
				this._ns.soundTransform = _loc_2;
			}
			
		}
		
		override public function play() : void
		{
			if (!playing)
			{
				super.play();
				if (this._ns)
				{
					this._timer.start();
					try
					{
						this._ns.play(url);
					}
					catch (err:SecurityError)
					{
						trace("流播放安全性错误：" + err.message);
					}
					callbackFunction(MediaPlayEvent.OPEN);
				}
			}
			else
			{
				trace("声音正处于播放状态，无法重复进行播放动作！");
			}
			
		}
		
		override public function pause() : void
		{
			if (playing)
			{
				super.pause();
				this._ns.pause();
				callbackFunction(MediaPlayEvent.PAUSE);
			}
			else
			{
				trace("声音正处于非播放状态，无法进行暂停播放动作！");
			}
			
		}
		
		override public function resume() : void
		{
			if (paused)
			{
				this._seekPause = false;
				super.play();
				this._ns.resume();
				callbackFunction(MediaPlayEvent.RESUME);
			}
			else
			{
				trace("声音正处于非暂停状态，无法进行暂停播放动作！");
			}
			
		}
		
		override public function stop() : void
		{
			if (!stopped)
			{
				super.stop();
				this._ns.pause();
				this._timer.stop();
				try
				{
					this._ns.close();
				}
				catch (err:Error)
				{
					trace("数据流关闭错误“" + err.message);
				}
				callbackFunction(MediaPlayEvent.STOP);
			}
			else
			{
				trace("声音正处于停止状态，无法重复进行停止播放动作！");
			}
			
		}
		
		override public function seek(param1:Number = 0) : void
		{
			if (!stopped)
			{
				this._seekTime = param1;
				this._seekPause = paused;
				this._ns.seek(param1);
				callbackFunction(MediaPlayEvent.SEEK);
			}
			else
			{
				trace("声音正处于停止状态，无法进行播放进度搜索动作！");
			}
			
		}
		
		override public function seekPercent(param1:Number = 0) : void
		{
			var _loc_2:* = param1 * _totalTime;
			this.seek(_loc_2);
			
		}
		
		override public function dispose() : void
		{
			if (this._ns != null)
			{
				this._ns.removeEventListener(NetStatusEvent.NET_STATUS, this.netStatusEventHandler);
				this._ns.removeEventListener(AsyncErrorEvent.ASYNC_ERROR, this.asyncErrorEventHandler);
				this._ns.removeEventListener(IOErrorEvent.IO_ERROR, this.ioErrorEventHandler);
				this._ns = null;
			}
			if (this._timer != null)
			{
				this._timer.removeEventListener(TimerEvent.TIMER, this.playingStateTimerEventHandler);
				this._timer = null;
			}
			if (this._nc != null)
			{
				this._nc.removeEventListener(AsyncErrorEvent.ASYNC_ERROR, this.asyncErrorEventHandler);
				this._nc.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.securityErrorEventHandler);
				this._nc = null;
			}
			super.dispose();
			
		}
		
		private function securityErrorEventHandler(event:SecurityErrorEvent) : void
		{
			callbackFunction(MediaPlayEvent.ERROR, event.text);
			
		}
		
		private function asyncErrorEventHandler(event:AsyncErrorEvent) : void
		{
			callbackFunction(MediaPlayEvent.ERROR, event.text);
			
		}
		
		private function ioErrorEventHandler(event:IOErrorEvent) : void
		{
			callbackFunction(MediaPlayEvent.IO_ERROR, event.text);
			
		}
		
		private function netStatusEventHandler(event:NetStatusEvent) : void
		{
			var _loc_3:Number = NaN;
			var _loc_2:* = event.info.code;
			switch(_loc_2)
			{
				case "NetStream.Play.Start":
				{
					this._startPlay = true;
					callbackFunction(MediaPlayEvent.PLAY);
					break;
				}
				case "NetStream.Play.Stop":
				{
					this.stop();
					callbackFunction(MediaPlayEvent.PLAY_COMPLETE);
					break;
				}
				case "NetStream.Buffer.Empty":
				case "NetStream.Seek.Notify":
				{
					_buffering = true;
					break;
				}
				case "NetStream.Buffer.Full":
				{
					_buffering = false;
					break;
				}
				case "NetStream.Seek.InvalidTime":
				{
					_loc_3 = event.info.message.details as Number;
					this.seek(_loc_3);
					break;
				}
				case "NetStream.Play.StreamNotFound":
				case "NetConnection.Connect.Failed":
				case "NetStream.Play.Failed":
				case "NetStream.Play.FileStructureInvalid":
				case "The MP4 doesn\'t contain any supported tracks":
				{
					callbackFunction(MediaPlayEvent.ERROR, _loc_2);
					break;
				}
				default:
				{
					break;
				}
			}
			
		}
		
		private function onMetaDataHandler(param1:Object) : void
		{
			_mediaData = param1;
			callbackFunction(MediaPlayEvent.INIT);
			_totalTime = param1.duration;
			if (this._ns.bufferTime > param1.duration)
			{
				var _loc_2:* = param1.duration;
				this._ns.bufferTime = param1.duration;
				_buffering = _loc_2;
			}
			
		}
		
		private function onCuePointHandler(param1:Object) : void
		{
			
		}
		
		private function playingStateTimerEventHandler(event:TimerEvent) : void
		{
			var _loc_2:Number = NaN;
			_loc_2 = 0;
			if (this._ns.bytesLoaded == this._ns.bytesTotal)
			{
				callbackFunction(MediaPlayEvent.COMPLETE);
			}
			else
			{
				_loadPercentage = this._ns.bytesLoaded / this._ns.bytesTotal;
				callbackFunction(MediaPlayEvent.PROGRESS);
			}
			if (_buffering)
			{
				_loc_2 = this._ns.bufferLength / this._ns.bufferTime;
				_bufferPercentage = _loc_2 > 1 ? (1) : (_loc_2);
				callbackFunction(MediaPlayEvent.BUFFERING);
			}
			else if (this._startPlay)
			{
				_playheadTime = this._seekPause ? (this._seekTime) : (this._ns.time);
				callbackFunction(MediaPlayEvent.PLAYING);
			}
			
		}
		
	}
}
